/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cl.orientesalud.business;

import cl.orientesalud.bd.ConectaBD;
import cl.orientesalud.dao.Dao;
import cl.orientesalud.dao.DescuentoDao;
import cl.orientesalud.dao.EstadoPagoDao;
import cl.orientesalud.dao.MedicoDao;
import cl.orientesalud.dao.PacienteDao;
import cl.orientesalud.dao.PagoDao;
import cl.orientesalud.dao.TipoPagoDao;
import cl.orientesalud.dao.TipoTratamientoDao;
import cl.orientesalud.dao.TratamientoDao;
import cl.orientesalud.dao.impl.DescuentoDaoImpl;
import cl.orientesalud.dao.impl.EstadoPagoDaoImpl;
import cl.orientesalud.dao.impl.MedicoDaoImpl;
import cl.orientesalud.dao.impl.PacienteDaoImpl;
import cl.orientesalud.dao.impl.PagoDaoImpl;
import cl.orientesalud.dao.impl.TipoPagoDaoImpl;
import cl.orientesalud.dao.impl.TipoTratamientoDaoImpl;
import cl.orientesalud.dao.impl.TratamientoDaoImpl;
import cl.orientesalud.dominio.Descuento;
import cl.orientesalud.dominio.EstadoPago;
import cl.orientesalud.dominio.Medico;
import cl.orientesalud.dominio.Paciente;
import cl.orientesalud.dominio.Pago;
import cl.orientesalud.dominio.TipoPago;
import cl.orientesalud.dominio.TipoTratamiento;
import cl.orientesalud.dominio.Tratamiento;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

/**
 *
 * @author nicolas
 */
public class TratamientoDelegate {
    PacienteDao daoPaciente;
    TipoTratamientoDao daoTipoTratamiento;
    DescuentoDao daoDescuento;
    MedicoDao daoMedico;
    TratamientoDao daoTratamiento;
    EstadoPagoDao daoEstadoPago;
    TipoPagoDao daoTipoPago;
    PagoDao daoPago;
    Dao dao;
    
    public Paciente obtenerPaciente(Paciente paciente) throws Exception{
        daoPaciente = new PacienteDaoImpl();
        return daoPaciente.obtenerPaciente(paciente);
    }
    
    public List<TipoTratamiento> obtenerTipoTratamientos() throws Exception{
        daoTipoTratamiento=new TipoTratamientoDaoImpl();

        return daoTipoTratamiento.obtenerTipoTratamientos();     
        
        
    }
    
    public List<Descuento> obtenerDescuentos() throws Exception{
        daoDescuento=new DescuentoDaoImpl();
        return daoDescuento.obtenerDescuentos();
    }

    public List<Medico> obtenerMedicos() throws Exception {
        daoMedico=new MedicoDaoImpl();
        return daoMedico.obtenerMedicos();
    }

    public List<Descuento> obtenerDescuentos(TipoTratamiento tipoTratamiento) throws Exception {
        daoDescuento=new DescuentoDaoImpl();
        return daoDescuento.obtenerDescuentos(tipoTratamiento);
    }
    
    public Integer insertarTratamiento(Tratamiento tratamiento) throws Exception{
        Integer idTratamiento=-1;
        try {
            daoTratamiento = new TratamientoDaoImpl();
            daoPago=new PagoDaoImpl();
            daoTratamiento.insertarTratamiento(tratamiento);
            idTratamiento=daoTratamiento.obtenerValorActualSeq("tratamiento_trat_id_seq");
            tratamiento.setId(idTratamiento);
            Iterator iterador=tratamiento.getDescuentos().iterator();
            
            while(iterador.hasNext()){
                Descuento descuento=(Descuento) iterador.next();
                daoTratamiento.insertarDescuento(tratamiento, descuento);
            }
            
            Long total=this.totalDescuentos(tratamiento)+tratamiento.getValorRepartir();
            Long cuota=(total - tratamiento.getPie())/tratamiento.getCuotas();
            Date today=new Date();
            Pago pago=new Pago();
            EstadoPago estado=new EstadoPago();
            TipoPago tipo=new TipoPago();
            tipo.setId(Constantes.PAGO_TIPO_PIE);
            estado.setId(Constantes.PAGO_ESTADO_PAGADA);
            pago.setEstado(estado);
            pago.setTipo(tipo);
            pago.setFechaPago(today);
            pago.setMonto(tratamiento.getPie());
            pago.setTratamiento(tratamiento);
            daoPago.insertarPago(pago);
            Integer idPago=daoTratamiento.obtenerValorActualSeq("pago_pag_id_seq");
            pago.setId(idPago);
            if(tratamiento.getPie()>this.totalDescuentos(tratamiento)){
                Long pagoMedico=(tratamiento.getPie()-this.totalDescuentos(tratamiento))/2;
                daoPago.insertarPagoMedico(pago,tratamiento.getMedico(),pagoMedico);
            }
            for(int i=0;i<tratamiento.getCuotas();i++){
                Date fecha=DateUtils.addDays(today, (i+1)*30);
                pago=new Pago();
                estado=new EstadoPago();
                tipo=new TipoPago();
                tipo.setId(Constantes.PAGO_TIPO_CUOTA);
                estado.setId(Constantes.PAGO_ESTADO_PENDIENTE);
                pago.setEstado(estado);
                pago.setTipo(tipo);
                pago.setTratamiento(tratamiento);
                pago.setFechaPago(fecha);
                pago.setMonto(cuota);
                daoPago.insertarPago(pago);               
            }
            daoTratamiento.commit();
            
        } catch (Exception ex) {
            daoTratamiento.rollback();
            throw new Exception(ex); 
        }
        
        return idTratamiento;
        
    }

    public Tratamiento obtenerTratamiento(Tratamiento tratamiento) throws Exception {
        daoTratamiento = new TratamientoDaoImpl();
        return daoTratamiento.obtenerTratamiento(tratamiento);
    }

    public List<EstadoPago> ObtenerEstados() throws Exception {
        daoEstadoPago=new EstadoPagoDaoImpl();
        return daoEstadoPago.obtenerEstadosPago();
    }

    public List ObtenerTipos() throws Exception {
       daoTipoPago=new TipoPagoDaoImpl();
       return daoTipoPago.obtenerTiposPago();
    }

    public List<Pago> obtenerPagos(Tratamiento tratamiento) throws Exception {
        daoPago=new PagoDaoImpl();
        return daoPago.obtenerPagos(tratamiento);
    }

    public Long totalDescuentos(Tratamiento tratamiento) throws Exception {
        daoDescuento=new DescuentoDaoImpl();
        Long total=daoDescuento.obtenerTotal(tratamiento)+tratamiento.getOtroDescuento();
        return total;
    }

    public Long totalPagado(Tratamiento tratamiento) throws Exception {
        daoPago=new PagoDaoImpl();
        return daoPago.totalPagado(tratamiento);
    }

    public void insertarPago(Pago pago,Tratamiento tratamiento) throws Exception {
        daoPago=new PagoDaoImpl();
        daoPago.insertarPago(pago);
        Long totalDescuentos=totalDescuentos(tratamiento);
        Long totalPagado=totalPagado(tratamiento);
        Long diferencia=0l;
        Long pagoMedico=0l;
        if(totalPagado>totalDescuentos){
            diferencia=totalPagado-pago.getMonto();
            if(diferencia<totalDescuentos){
                pagoMedico=(pago.getMonto()-(totalDescuentos-totalPagado))/2;
            }
            else if(diferencia==totalDescuentos){
                pagoMedico=0l;
            }
            else{
                pagoMedico=pago.getMonto()/2;
            }
            
        }  
         if(pagoMedico>0)
            daoPago.insertarPagoMedico(pago, pago.getTratamiento().getMedico(), pagoMedico);
        daoPago.commit();
    }

    public Pago obtenerPago(Pago pago) throws Exception {
        daoPago=new PagoDaoImpl();
        return daoPago.obtenerPago(pago);
    }

    public void modificarPago(Pago pago) throws Exception{
        try {
            
            
            daoPago=new PagoDaoImpl();
            daoPago.actualizarPago(pago);
            Long totalDescuentos=totalDescuentos(pago.getTratamiento());
            Long totalPagado=totalPagado(pago.getTratamiento());
            Long diferencia=0l;
            Long pagoMedico=0l;
            if(pago.getEstado().getId()==Constantes.PAGO_ESTADO_PAGADA){
                if(totalPagado>totalDescuentos){
                     diferencia=totalPagado-pago.getMonto();
                     if(diferencia<totalDescuentos){
                        pagoMedico=(pago.getMonto()-(totalDescuentos-diferencia))/2;
                     }
                     else if(diferencia==totalDescuentos){
                        pagoMedico=0l;
                     }
                     else{
                        pagoMedico=pago.getMonto()/2;
                     }
                }
              
                if(pagoMedico>0)
                    daoPago.insertarPagoMedico(pago, pago.getTratamiento().getMedico(), pagoMedico);
            }
            if(pago.getEstado().getId()==Constantes.PAGO_ESTADO_INVALIDO || pago.getEstado().getId()==Constantes.PAGO_ESTADO_PENDIENTE){
                daoPago.eliminarPagoMedico(pago, pago.getTratamiento().getMedico());
            }
            daoPago.commit();
        } catch (Exception ex) {
            daoPago.rollback();
            throw new Exception(ex);
        }
    }

    public Connection obtenerConexion() throws Exception {
        return ConectaBD.getInstance().getConn();
        
    }

    public List<Tratamiento> obtenerTratamientos(Medico medico) throws Exception{
        daoTratamiento = new TratamientoDaoImpl();
        return daoTratamiento.getTratamientos(medico);
    }

    public List<Tratamiento> obtenerTratamientos(Paciente paciente) throws Exception {
        daoTratamiento = new TratamientoDaoImpl();
        return daoTratamiento.getTratamientos(paciente);
    }
    
    public List<Tratamiento> obtenerTratamientos(Tratamiento tratamiento) throws Exception {
        daoTratamiento = new TratamientoDaoImpl();
        return daoTratamiento.getTratamientos(tratamiento);
    }

    public void modificarTipoTratamiento(TipoTratamiento tipoTratamiento) throws Exception {
        daoTipoTratamiento=new TipoTratamientoDaoImpl();
        daoTipoTratamiento.actualizarTipoTratamiento(tipoTratamiento);
        daoTipoTratamiento.commit();
    }

    public void modificarDescuento(Descuento desc) throws Exception {
        daoDescuento=new DescuentoDaoImpl();
        daoDescuento.modificarDescuento(desc);
        daoDescuento.commit();
    }

    public void insertarDescuento(Descuento desc) throws Exception {
        daoDescuento=new DescuentoDaoImpl();
        daoDescuento.ingresarDescuento(desc);
        daoDescuento.commit();
    }

    public void generarExcel() throws FileNotFoundException, IOException {
        HSSFWorkbook objWB = new HSSFWorkbook();
        HSSFSheet hoja1=objWB.createSheet("Hoja1");
        HSSFRow fila = hoja1.createRow((short)1);
        HSSFFont fuente = objWB.createFont();
        fuente.setFontHeightInPoints((short)11);
        fuente.setFontName(fuente.FONT_ARIAL);
        fuente.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

        // Luego creamos el objeto que se encargará de aplicar el estilo a la celda
        HSSFCellStyle estiloCelda = objWB.createCellStyle();
        estiloCelda.setWrapText(true);
        estiloCelda.setAlignment(HSSFCellStyle. ALIGN_JUSTIFY);
        estiloCelda.setVerticalAlignment(HSSFCellStyle.VERTICAL_TOP);
        estiloCelda.setFont(fuente);

        // También, podemos establecer bordes...
        estiloCelda.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM);
        estiloCelda.setBottomBorderColor((short)8);
        estiloCelda.setBorderLeft(HSSFCellStyle.BORDER_MEDIUM);
        estiloCelda.setLeftBorderColor((short)8);
        estiloCelda.setBorderRight(HSSFCellStyle.BORDER_MEDIUM);
        estiloCelda.setRightBorderColor((short)8);
        estiloCelda.setBorderTop(HSSFCellStyle.BORDER_MEDIUM);
        estiloCelda.setTopBorderColor((short)8);

        // Establecemos el tipo de sombreado de nuestra celda
        estiloCelda.setFillForegroundColor((short)22);
        estiloCelda.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

        // Creamos la celda, aplicamos el estilo y definimos
        // el tipo de dato que contendrá la celda
        HSSFCell celda = fila.createCell((short)0);
        celda.setCellStyle(estiloCelda);
        celda.setCellType(HSSFCell.CELL_TYPE_STRING);

        // Finalmente, establecemos el valor
        celda.setCellValue("Un valor");
        String strNombreArchivo = "/home/nicolas/archivo.xls";
        File objFile = new File(strNombreArchivo);
        FileOutputStream archivoSalida = new FileOutputStream(objFile);
        objWB.write(archivoSalida);
        archivoSalida.close();
    }
}
